/**
 * Copyright (C) 2010 DustedPixels.com
 */
package com.dustedpixels.cirt.applet;

import java.applet.Applet;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;

import com.dustedpixels.cirt.Cirt;
import com.dustedpixels.cirt.CirtRunnables;
import com.dustedpixels.cirt.awt.VideoComponents;
import com.dustedpixels.cirt.awt.VideoImages;
import com.dustedpixels.cirt.model.machine.spectrum.ZxSpectrum48;

/**
 * EmuApplet
 *
 * @author Michal Pociecha-Los (micapolos@gmail.com)
 */
public final class CirtApplet extends Applet {

  private static final int WIDTH = 352;
  private static final int HEIGHT = 304;
  private static final int ZOOM = 1;
  
  private static final long serialVersionUID = 7772471674240682837L;
  
  private BufferedImage videoImage;

  private Thread mainLoopThread;

  private byte[] videoBytes;

  private byte[] ram1Bytes;
  private byte[] backBuffer;

  @Override
  public void init() {
    setSize(WIDTH * ZOOM, HEIGHT * ZOOM);
    
    FlowLayout flowLayout = new FlowLayout();
    flowLayout.setHgap(0);
    flowLayout.setVgap(0);
    setLayout(flowLayout);
    
    setSize(WIDTH * ZOOM, HEIGHT * ZOOM);
    
    byte[] romBytes = new byte[16384];
    ram1Bytes = new byte[16384];
    byte[] ram2Bytes = new byte[32768];
    videoBytes = new byte[352 * 304];
    backBuffer = new byte[352 * 304];

    ZxSpectrum48 zx = new ZxSpectrum48(romBytes, ram1Bytes, ram2Bytes, videoBytes);

    byte n = (byte) 0xC0;
    byte b = (byte) 0xFF;
    byte[] redPalette = new byte[] {0, 0, n, n, 0, 0, n, n, 0, 0, b, b, 0, 0, b, b};
    byte[] greenPalette = new byte[] {0, 0, 0, 0, n, n, n, n, 0, 0, 0, 0, b, b, b, b};
    byte[] bluePalette = new byte[] {0, n, 0, n, 0, n, 0, n, 0, b, 0, b, 0, b, 0, b};

    videoImage = VideoImages.newPaletteImage(
        WIDTH,
        HEIGHT,
        backBuffer,
        redPalette,
        greenPalette, 
        bluePalette);
    
    final Component videoComponent =
        VideoComponents.newLightweightComponent(
            getGraphicsConfiguration(), 
            videoImage);
    videoComponent.setSize(WIDTH * ZOOM, HEIGHT * ZOOM);
    add(videoComponent);
    
    Runnable onRepaint = new Runnable() {
      public void run() {
        synchronized (videoImage) {
          System.arraycopy(videoBytes, 0, backBuffer, 0, videoBytes.length);
        }
        videoComponent.repaint();
      }      
    };
    
    Runnable mainLoop = CirtRunnables.newRunnable(onRepaint, zx, videoBytes);
    mainLoopThread = new Thread(mainLoop);     
  }
  
  @Override
  public void start() {
    try {
      InputStream inputStream = Cirt.class.getClassLoader().getResourceAsStream("DynamiteDan.scr");
      try {
        for (int i = 0; i < 6912; i++) {
          ram1Bytes[i] = (byte) inputStream.read();
        }
      } finally {
        inputStream.close();
      }
    } catch (IOException e) {
      System.out.println("Error loading image");
      return;
    }
    System.out.println("Image loaded");
    
    mainLoopThread.start();    
  }
  
  @Override
  public void stop() {
    mainLoopThread.interrupt();
  }
}
